package com.cutefool.zero.code.core.domain;

import com.cutefool.dsl.mybatis.core.objects.BasicsDomain;
import com.fasterxml.jackson.annotation.JsonAlias;
import jakarta.annotation.Generated;
import java.sql.JDBCType;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.UnaryOperator;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.mybatis.dynamic.sql.SqlBuilder;
import org.mybatis.dynamic.sql.SqlColumn;
import org.mybatis.dynamic.sql.insert.InsertDSL;
import org.mybatis.dynamic.sql.insert.MultiRowInsertDSL;
import org.mybatis.dynamic.sql.update.UpdateDSL;
import org.mybatis.dynamic.sql.update.UpdateModel;

@Data
@EqualsAndHashCode(callSuper = true)
public class SerialRuleItem extends BasicsDomain<SerialRuleItem> {
    @Generated("org.mybatis.generator.api.MyBatisGenerator")
    @JsonAlias("name_")
    private String name;

    @Generated("org.mybatis.generator.api.MyBatisGenerator")
    @JsonAlias("RULE_ID_")
    private Long ruleId;

    @Generated("org.mybatis.generator.api.MyBatisGenerator")
    @JsonAlias("expression_")
    private String expression;

    private static final SerialRuleItem instance = new SerialRuleItem();

    private static final Table table = new Table();

    public static SerialRuleItem instance() {
        return instance;
    }

    @Override
    public Table table() {
        return table;
    }

    @Override
    @SuppressWarnings("DuplicatedCode")
    public UnaryOperator<InsertDSL<SerialRuleItem>> insert() {
        return (InsertDSL<SerialRuleItem> dsl) -> {
            dsl.map(table.id).toProperty("id");
            dsl.map(table.name).toProperty("name");
            dsl.map(table.ruleId).toProperty("ruleId");
            dsl.map(table.expression).toProperty("expression");
            return dsl;
        };
    }

    @Override
    @SuppressWarnings("DuplicatedCode")
    public UnaryOperator<MultiRowInsertDSL<SerialRuleItem>> insertMultiple() {
        return (MultiRowInsertDSL<SerialRuleItem> dsl) -> {
            dsl.map(table.id).toProperty("id");
            dsl.map(table.name).toProperty("name");
            dsl.map(table.ruleId).toProperty("ruleId");
            dsl.map(table.expression).toProperty("expression");
            return dsl;
        };
    }

    @Override
    public void updateAllColumns(UpdateDSL<UpdateModel> dsl) {
        dsl.set(table.name).equalTo(this::getName)
           .set(table.ruleId).equalTo(this::getRuleId)
           .set(table.expression).equalTo(this::getExpression);
        if(Objects.nonNull(getId())) {
            dsl.where(table.id, SqlBuilder.isEqualTo(this::getId));
        }
    }

    @Override
    public void updateSelectiveColumns(UpdateDSL<UpdateModel> dsl) {
        dsl.set(table.name).equalToWhenPresent(this::getName)
           .set(table.ruleId).equalToWhenPresent(this::getRuleId)
           .set(table.expression).equalToWhenPresent(this::getExpression);
        if(Objects.nonNull(getId())) {
            dsl.where(table.id, SqlBuilder.isEqualTo(this::getId));
        }
    }

    @Override
    @SuppressWarnings("all")
    public SqlColumn[] columns() {
        return new SqlColumn[]{table.id, table.name, table.ruleId, table.expression};
    }

    @Override
    public Map<String, SqlColumn<?>> columnsMap() {
        Map<String, SqlColumn<?>> maps = new LinkedHashMap<>(4);
        maps.put("id", table.id);
        maps.put("name", table.name);
        maps.put("ruleId", table.ruleId);
        maps.put("expression", table.expression);
        return maps;
    }

    @Override
    public SqlColumn<Long> id() {
        return table.id;
    }

    public static final class Table extends org.mybatis.dynamic.sql.AliasableSqlTable<Table> {
        public final SqlColumn<Long> id = column("ID_", JDBCType.BIGINT);

        public final SqlColumn<String> name = column("name_", JDBCType.VARCHAR);

        public final SqlColumn<Long> ruleId = column("RULE_ID_", JDBCType.BIGINT);

        public final SqlColumn<String> expression = column("expression_", JDBCType.VARCHAR);

        public Table() {
            super("DICTIONARY_serial_RULE_ITEM", Table::new);
        }
    }
}